// 挖矿改造相关接口
package v1

import (
	"errors"
	"github.com/gin-gonic/gin"
	"github.com/gin-gonic/gin/binding"
	"strconv"
	"zimuzu_cvn_web_api/config"
	"zimuzu_cvn_web_api/model"
	"zimuzu_cvn_web_api/pkg/drive/redis"
	"zimuzu_cvn_web_api/pkg/e"
	"zimuzu_cvn_web_api/pkg/errno"
	"zimuzu_cvn_web_api/router/api"
	"zimuzu_cvn_web_api/router/api/app/middleware"
	"zimuzu_cvn_web_api/service"
	"zimuzu_cvn_web_api/service/flows"
)

type MiningAPI struct {
}

func (a MiningAPI) Name() string {
	return "mining API"
}

func (a MiningAPI) Bind() {
	miningAPI := config.C.Router.Group("/v1/app/mining", middleware.TrackLog(), middleware.AuthMiddleware())
	{
		miningAPI.GET("role", miningRole)
		miningAPI.GET("info", miningInfo)
		miningAPI.GET("join", joinMining)
		miningAPI.GET("node/list", userNodeList)
		miningAPI.GET("profit/list", profitList)
		miningAPI.GET("profit/detail", profitDetail)
		miningAPI.GET("profit/detail/more", profitDetailMore)
		miningAPI.GET("profit/detail/net", profitDetailNet)
		miningAPI.GET("profit/detail/date", profitDetailDate)
		miningAPI.GET("node/pledge", nodePledge)
		miningAPI.POST("node/pledge/batch", nodePledgeBatch)
		miningAPI.GET("payment/reissue", paymentReissue)
		miningAPI.GET("node/fix/unPledge", fixUnPledge)
		miningAPI.GET("node/fix/task", fixUnPledgeTask)
		miningAPI.GET("node/delete", deleteUserNode)
	}
}

func profitDetailNet(c *gin.Context) {
	date := c.Query("date")
	res, err := flows.GetNetSourceNetData(date)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "获取成功"
	api.SendResponse(c, errno.OK, res)
}

// 软删除节点
func deleteUserNode(c *gin.Context) {
	uid, _ := service.GetUserIdByRequest(c)
	nodeId, err := strconv.ParseInt(c.Query("node_id"), 10, 64)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	err = flows.DeleteOfflineNodeByNodeId(uid, nodeId)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "删除成功"
	api.SendResponse(c, errno.OK, nil)
}

// 修复任务未执行成功
func fixUnPledgeTask(c *gin.Context) {
	key := c.Query("key")
	if key != config.C.FlowKey {
		api.SendResponse(c, errno.IllegalErr, nil)
		return
	}

	taskId, _ := strconv.ParseInt(c.Query("task_id"), 10, 64)
	Task, err := model.GetUserDrawTask(taskId)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	err = service.DoDrawTask(Task, 1)
	if err != nil {
		e.Log("err", err.Error())
		api.SendResponse(c, err, nil)
		return
	}

	errno.OK.Info = "修复成功"
	api.SendResponse(c, errno.OK, nil)
}

// 修复质押退回失败数据
func fixUnPledge(c *gin.Context) {
	key := c.Query("key")
	if key != config.C.FlowKey {
		api.SendResponse(c, errno.IllegalErr, nil)
		return
	}

	UidInt64, _ := strconv.ParseInt(c.Query("uid"), 10, 64)
	NodeIdInt64, _ := strconv.ParseInt(c.Query("node_id"), 10, 64)
	err := flows.SingleNodePledge(UidInt64, NodeIdInt64, 3)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	errno.OK.Info = "修复成功"
	api.SendResponse(c, errno.OK, nil)
}

// 补发数据
// Auth: hzp
func paymentReissue(c *gin.Context) {
	key := c.Query("key")
	if key != config.C.FlowKey {
		api.SendResponse(c, errno.IllegalErr, nil)
		return
	}

	err := service.PaymentForMgNode()
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "补发成功"
	api.SendResponse(c, errno.OK, nil)
}

// 旷工角色
// Auth: hzp
// 角色：1-普通用户  2-旷工  3-超级节点
func miningRole(c *gin.Context) {

	uid, _ := service.GetUserIdByRequest(c)
	res, err := flows.GetMinerRole(uid)
	if err != nil {
		api.SendResponse(c, errors.New("查询旷工角色失败"), err.Error())
		return
	}

	errno.OK.Info = "成功"
	api.SendResponse(c, errno.OK, res)
	return
}

/*
 * @ Description: 挖矿详情
 * @ update: 2020-03-12
 * @ update desc: 更新看板内容显示
 * @ update by: hzp
 **/
func miningInfo(c *gin.Context) {

	e.Log("info", "请求查询挖矿详情接口开始")
	uid, _ := service.GetUserIdByRequest(c)
	res, err := service.GetMiningInfo(uid)
	if err != nil {
		api.SendResponse(c, errors.New("查询挖矿详情失败"), err.Error())
		return
	}

	errno.OK.Info = "获取挖矿详情成功"
	api.SendResponse(c, errno.OK, res)
	return
}

// Auth: hzp
// 加入旷工
func joinMining(c *gin.Context) {
	var params model.MinerSuperId
	err := c.ShouldBindWith(&params, binding.Query)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	uid, _ := service.GetUserIdByRequest(c)
	err = flows.UserJoinSuperNode(params.SuperUid, uid)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	errno.OK.Info = "申请成功"
	api.SendResponse(c, errno.OK, nil)
	return
}

/*
 * @ Auth: hzp
 * @ 挖矿改造 节点列表
 **/
func userNodeList(c *gin.Context) {
	var params model.PageParams
	if params.Page < 1 {
		params.Page = 1
		params.Per = 20
	}
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	uid, _ := service.GetUserIdByRequest(c)
	res, err := flows.GetUserNodeList(uid, params.Per, params.Page)
	if err != nil {
		api.SendResponse(c, errors.New("请求失败"), nil)
		return
	}
	errno.OK.Info = "获取节点成功"
	api.SendResponse(c, errno.OK, res)
	return
}

// 收益详情列表
// Auth: hzp
func profitList(c *gin.Context) {
	var params model.PageParams
	if params.Page < 1 {
		params = model.NewDefaultPageParams()
	}
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	uid, _ := service.GetUserIdByRequest(c)
	//调用收益明细列表接口获取数据
	res, err := model.GetUserProfitListFromDB(uid, params.Page, params.Per)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "获取收益详情成功"
	api.SendResponse(c, errno.OK, res)
	return
}

// 收益详情 详情
// Auth: hzp
func profitDetail(c *gin.Context) {
	var params model.ListIdParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	//调用收益详情接口获取数据
	res, err := flows.GetUserNodeProfitDetail(params.ListId)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}
	errno.OK.Info = "获取收益详情成功"
	api.SendResponse(c, errno.OK, res)
	return
}

// 单节点质押&解除
// Auth: hzp
func nodePledge(c *gin.Context) {

	var params model.NodePledgeParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	uid, _ := service.GetUserIdByRequest(c)
	// 调用单节点处理
	err = flows.SingleNodePledge(uid, params.NodeId, params.Way)
	if err != nil {
		// api.SendResponse(c, errno.PledgeStatusErr, nil)
		api.SendResponse(c, err, nil)
		return
	}

	// 质押完成之后删掉页面缓存数据
	cacheKey := service.UserNodeBoardDataCache(uid)
	redis.UnDelete(cacheKey)
	flows.DeleteUserNodeListKey(uid)

	errno.OK.Info = "处理成功"
	api.SendResponse(c, errno.OK, nil)
	return
}

// 批量节点质押&解除
// Auth: hzp
func nodePledgeBatch(c *gin.Context) {

	var params model.NodePledgeBatchParams
	err := c.BindJSON(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	uid, _ := service.GetUserIdByRequest(c)
	// 参数校验: 2-质押  3-解除质押
	if params.Way != 2 && params.Way != 3 {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}

	// 批量质押情况下要提前判断是否余额充足
	if params.Way == 2 {
		//判断余额、冻结金额是否足够
		oldAmount, err := model.GetCvnAmount(config.C.DB.DB, uid)
		if err != nil {
			api.SendResponse(c, errno.GetDataErr, nil)
			return
		}
		lenFlo, _ := strconv.ParseFloat(strconv.Itoa(len(params.NodeId)), 64)
		if oldAmount.Balance-lenFlo*e.SinglePledgeCvn < 0 {
			api.SendResponse(c, errno.WalletNotEnoughERR, nil)
			return
		}
	}

	// 调用单节点处理
	errDo := 0
	for _, k := range params.NodeId {
		err = flows.SingleNodePledge(uid, k, params.Way)
		if err != nil {
			errDo++
		}
	}

	if errDo > 0 {
		errno.PledgeStatusBatchErr.Info += "失败" + strconv.Itoa(errDo) + "条"
		api.SendResponse(c, errno.PledgeStatusBatchErr, nil)
		return
	}

	// 质押完成之后删掉页面缓存数据
	cacheKey := e.UserRedisPrefix + strconv.FormatInt(uid, 10) + e.UserMiningInfoCacheKey + "node:data"
	redis.UnDelete(cacheKey)
	flows.DeleteUserNodeListKey(uid)

	errno.OK.Info = "批量处理成功"
	api.SendResponse(c, errno.OK, nil)
	return
}

func profitDetailMore(c *gin.Context) {

	var params model.PageParams
	if params.Page < 1 {
		params = model.NewDefaultPageParams()
	}
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	uid, _ := service.GetUserIdByRequest(c)
	res, err := flows.ProfitDetailRelation(uid, params.Page, params.Per)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	errno.OK.Info = "获取详情主页数据成功"
	api.SendResponse(c, errno.OK, res)
	return
}

func profitDetailDate(c *gin.Context) {

	var params model.TheDateNodePaymentParams
	err := c.ShouldBindQuery(&params)
	if err != nil {
		api.SendResponse(c, errno.ParamsError, nil)
		return
	}
	if params.Page < 1 {
		params.Page = 1
		params.Per = 20
	}
	uid, _ := service.GetUserIdByRequest(c)
	res, err := flows.TheDataProfitDetailRelation(uid, params.Source, params.Date, params.Page, params.Per)
	if err != nil {
		api.SendResponse(c, err, nil)
		return
	}

	errno.OK.Info = "获取指定结点详情数据成功"
	api.SendResponse(c, errno.OK, res)
	return
}
